import sys
import os

# 获取当前文件所在目录的父目录（即项目根目录）
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
if project_root not in sys.path:
    sys.path.append(project_root)

from concurrent.futures import ThreadPoolExecutor
from queue import Queue
import threading
from DrissionPage import ChromiumPage, ChromiumOptions
import time,random
import numpy as np
from common.start import get_random_proxy_ks, kuaishou_logger

def ease_out_quad(x):
    return 1 - (1 - x) * (1 - x)

def ease_out_quart(x):
    return 1 - pow(1 - x, 4)

def ease_out_expo(x):
    if x == 1:
        return 1
    else:
        return 1 - pow(2, -10 * x)

def get_tracks_2(distance, seconds=1, ease_func=ease_out_quart):
    tracks = [0]
    offsets = [0]
    for t in np.arange(0.0, seconds, 0.1):
        ease = ease_func
        offset = round(ease(t / seconds) * distance)
        tracks.append(offset - offsets[-1])
        offsets.append(offset)

    return tracks

def init_browser():
    """初始化独立浏览器配置"""
    co = ChromiumOptions().auto_port()
    # co.headless()
    co.set_argument('--no-sandbox')  # 无沙盒模式
    co.set_argument('--disable-gpu')
    co.set_argument('--headless=new')  # 无界面系统添加
    co.set_argument("--disable-blink-features=AutomationControlled")
    co.set_user_agent(
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36')
    co.set_argument('--charset=UTF-8')  # 设置编码为 UTF-8
    co.incognito(True)
    return ChromiumPage(addr_or_opts=co)

def fetch_single_did(browser):
    """单个获取任务"""
    try:
        browser.clear_cache()
        browser.get("https://www.kuaishou.com/?isHome=1")
        time.sleep(5)
        cookies = browser.cookies()
        for data in cookies:
            if data['name'] == 'did':
                return data['value']
        return None
    finally:
        browser.close()  # 关闭当前实例
        # browser.quit()

def concurrent_get_dids():
    """并发获取多个did"""
    results = []
    with ThreadPoolExecutor(max_workers=5) as executor:
        futures = []    

        for i in range(5):
            browser = init_browser()  # 每个任务独立实例
            futures.append(executor.submit(fetch_single_did, browser))
            # futures.append(executor.submit(get_new_did))
        
        
        for future in futures:
            if (did := future.result()):
                results.append(did)
    return results


did_cd_lock = threading.Lock()
DID_CD = 3
DIDS_IN_CD = []
def add_did_to_cd(did):
    """
    did冷却
    
    """
    with did_cd_lock:
        DIDS_IN_CD.append(did)
    kuaishou_logger.warning(f"did: {did} 进入冷却")

    # 创建定时任务，在一段时间后从cdlist中移除
    def remove_from_cdlist():
        time.sleep(DID_CD)
        with did_cd_lock:
            if did in DIDS_IN_CD:
                DIDS_IN_CD.remove(did)
                kuaishou_logger.info(f"did: {did} 冷却完毕")

    # 启动后台线程处理黑名单超时
    threading.Thread(target=remove_from_cdlist, daemon=True).start()


DID_LOCK = threading.Lock()
DIDS = []
def get_dids():
    global DIDS
    with DID_LOCK:
        kuaishou_logger.info("正在更新did......")
        DIDS = concurrent_get_dids()
        kuaishou_logger.info(f"did更新成功:{DIDS}")

def get_random_did():
    with DID_LOCK:
        available_dids = [did for did in DIDS if did not in DIDS_IN_CD]
        if len(available_dids) == 0:
            kuaishou_logger.info("DID池无可用DID...")
            did = random.choice(DIDS)
            return did
        did = random.choice(available_dids)
        return did


co = ChromiumOptions().auto_port()
co.headless()
co.set_argument('--no-sandbox')  # 无沙盒模式
co.set_argument('--disable-gpu')
co.set_argument('--disable-dev-shm-usage')
co.set_argument('--headless=new')  # 无界面系统添加
co.set_argument("--disable-blink-features=AutomationControlled")
co.set_user_agent(
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36')
co.set_argument('--charset=UTF-8')  # 设置编码为 UTF-8
co.incognito(True)

page = None 

def page_init():
    global page
    page = ChromiumPage(addr_or_opts=co)
    return 

def page_close():
    global page
    try:
        page.close()
        page.quit()
    except:
        pass
    return

def get_new_did():
    global page
    retries = 0
    while retries < 3:
        try:              
            page.clear_cache()
            page.get("https://www.kuaishou.com/?isHome=1")
            time.sleep(5)
            page.get("https://www.kuaishou.com/?isHome=1")
            cookies = page.cookies()

            for data in cookies:
                if data['name'] == 'did':
                    print(f"did : {data['value']}")
                    return data['value']
            return ""
        except  Exception as e:
            kuaishou_logger.error(f"Error Type: {type(e).__name__}")
            kuaishou_logger.error(f"Error: {e}")
            try:
                page.close()
                page.quit()
            except Exception as e:
                kuaishou_logger.error(f"Error Type: {type(e).__name__}")
                kuaishou_logger.error(f"Error: {e}")

            page = ChromiumPage(addr_or_opts=co)
            kuaishou_logger.info("已重新连接浏览器......")
            retries += 1
            time.sleep(1)
    

def get_new_did_by_page(page : ChromiumPage):     
    page.clear_cache()
    page.get("https://www.kuaishou.com/?isHome=1")
    time.sleep(5)
    page.get("https://www.kuaishou.com/?isHome=1")
    cookies = page.cookies()

    for data in cookies:
        if data['name'] == 'did':
            return data['value']
    return ""


    

class FIFOProcessor:
    def __init__(self):
        self.did_queue = Queue()
        self.did_wait_queue = Queue()

    def get_size(self):
        return self.did_queue.qsize()
    
    def add_did(self,did):
        kuaishou_logger.info(f"did: {did} 添加到队列,当前队列大小：{self.did_queue.qsize()}")
        self.did_queue.put(did)
    
    def pop_did(self):
        did = self.did_queue.get()
        kuaishou_logger.info(f"did: {did} 从队列中取出,当前队列大小：{self.did_queue.qsize()}")
        return did

    def add_did_ex(self,did_ex):
        self.did_wait_queue.put(did_ex)


    def pop_did_ex(self):
        did_ex = self.did_wait_queue.get()
        return did_ex
    